package com.huhu.levelloader;

import java.util.ArrayList;

import org.andengine.engine.Engine;
import org.andengine.engine.camera.BoundCamera;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.PathModifier;
import org.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.andengine.entity.modifier.PathModifier.Path;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.sprite.Sprite;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.extension.tmx.TMXObject;
import org.andengine.extension.tmx.TMXObjectGroup;
import org.andengine.extension.tmx.TMXTiledMap;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.util.modifier.ease.EaseSineInOut;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.huhu.interfaces.IPlayer;
import com.huhu.manager.ResourcesManager;
import com.huhu.manager.SceneManager;
import com.huhu.objects.Player;
import com.huhu.scenes.GameScene;

public class LevelLoader1_5 extends LevelLoader {
	private HUD gameHUD;
	private Player player;
	private static final FixtureDef FIXTURE_DEF = PhysicsFactory
			.createFixtureDef(0, 0, 0);
	private boolean gameOverDisplayed = false;
	private boolean levelCompleteDisplayed = false;

	private Sprite box1Sprite;
	private Body box1Body;

	private Sprite box2Sprite;
	private Body box2Body;
	
	private Sprite box3Sprite;
	private Body box3Body;
	
	private Sprite rocketSprite;
	private boolean doRocket = false;

	public LevelLoader1_5(Engine engine, GameScene scene, BoundCamera camera,
			PhysicsWorld physicsWorld, VertexBufferObjectManager vbom) {
		super(engine, scene, camera, physicsWorld, vbom);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void createHUD() {
		gameHUD = new HUD();

		final Sprite spriteMoveLeft = new Sprite(10, 520,
				resourcesManager.move_left_region, vbom) {
			@Override
			public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
					float pTouchAreaLocalX, float pTouchAreaLocalY) {
				if (pSceneTouchEvent.isActionDown()) {
					player.setDirection(false);
					player.setRunning();
				} else {
					player.setStopping();
				}
				return true;
			}
		};
		gameHUD.registerTouchArea(spriteMoveLeft);
		gameHUD.attachChild(spriteMoveLeft);

		final Sprite spriteMoveRight = new Sprite(135, 520,
				resourcesManager.move_right_region, vbom) {
			@Override
			public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
					float pTouchAreaLocalX, float pTouchAreaLocalY) {
				if (pSceneTouchEvent.isActionDown()) {
					player.setDirection(true);
					player.setRunning();
				} else {
					player.setStopping();
				}
				return true;
			}
		};
		gameHUD.registerTouchArea(spriteMoveRight);
		gameHUD.attachChild(spriteMoveRight);

		final Sprite spriteJump = new Sprite(876, 520,
				resourcesManager.jump_region, vbom) {
			@Override
			public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
					float pTouchAreaLocalX, float pTouchAreaLocalY) {
				if (pSceneTouchEvent.isActionDown()) {
					player.jump();
				}
				return true;
			}
		};
		gameHUD.registerTouchArea(spriteJump);
		gameHUD.attachChild(spriteJump);

		final Sprite spriteBack = new Sprite(10, 10,
				resourcesManager.back_region, vbom) {
			@Override
			public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
					float pTouchAreaLocalX, float pTouchAreaLocalY) {
				SceneManager.getInstance().getCurrentScene().onBackKeyPressed();
				return true;
			}
		};
		gameHUD.registerTouchArea(spriteBack);
		gameHUD.attachChild(spriteBack);

		camera.setHUD(gameHUD);

	}

	@Override
	public IPlayer createPlatform(TMXTiledMap mTMXTiledMap) {
		ArrayList<TMXObjectGroup> mTMXObjectGroups = mTMXTiledMap
				.getTMXObjectGroups();
		for (TMXObjectGroup mTMXObjectGroup : mTMXObjectGroups) {
			if (mTMXObjectGroup.getTMXObjectGroupProperties()
					.containsTMXProperty("platformobject", "true")) {
				for (TMXObject mTMXObject : mTMXObjectGroup.getTMXObjects()) {
					Rectangle rectangle = new Rectangle(mTMXObject.getX(),
							mTMXObject.getY(), mTMXObject.getWidth(),
							mTMXObject.getHeight(), vbom);
					Body body = PhysicsFactory.createBoxBody(physicsWorld,
							rectangle, BodyType.StaticBody, FIXTURE_DEF);
					body.setUserData("platform_body_data");
					rectangle.setVisible(false);
					scene.attachChild(rectangle);
				}
			} else if (mTMXObjectGroup.getTMXObjectGroupProperties()
					.containsTMXProperty("platformdynamic", "true")) {
				for (TMXObject mTMXObject : mTMXObjectGroup.getTMXObjects()) {
					final float x = mTMXObject.getX();
					final float y = mTMXObject.getY();
					final float width = mTMXObject.getWidth();
					final float height = mTMXObject.getHeight();
					if (mTMXObject.getName().equals("dynamic1")) {
						final Sprite dynamic1Sprite = new Sprite(x, y,
								resourcesManager.dynamic_14_region, vbom);
						Body dynamic1Body = PhysicsFactory.createBoxBody(
								physicsWorld, dynamic1Sprite,
								BodyType.StaticBody, FIXTURE_DEF);
						dynamic1Body.setUserData("dynamic_body_data");
						scene.attachChild(dynamic1Sprite);
						physicsWorld
								.registerPhysicsConnector(new PhysicsConnector(
										dynamic1Sprite, dynamic1Body, true,
										false));
					} else if (mTMXObject.getName().equals("dynamic2")) {
						final Sprite dynamic2Sprite = new Sprite(x, y,
								resourcesManager.dynamic_6_region, vbom);
						Body dynamic2Body = PhysicsFactory.createBoxBody(
								physicsWorld, dynamic2Sprite,
								BodyType.StaticBody, FIXTURE_DEF);
						dynamic2Body.setUserData("dynamic_body_data");
						scene.attachChild(dynamic2Sprite);
						physicsWorld
								.registerPhysicsConnector(new PhysicsConnector(
										dynamic2Sprite, dynamic2Body, true,
										false));
					} else if (mTMXObject.getName().equals("dynamic3")) {
						final Sprite dynamic3Sprite = new Sprite(x, y,
								resourcesManager.dynamic_4_region, vbom);
						Body dynamic3Body = PhysicsFactory.createBoxBody(
								physicsWorld, dynamic3Sprite,
								BodyType.StaticBody, FIXTURE_DEF);
						dynamic3Body.setUserData("dynamic_body_data");
						scene.attachChild(dynamic3Sprite);
						physicsWorld
								.registerPhysicsConnector(new PhysicsConnector(
										dynamic3Sprite, dynamic3Body, true,
										false));
					} else if (mTMXObject.getName().equals("dynamic4")) {
						final Sprite dynamic4Sprite = new Sprite(x, y,
								resourcesManager.dynamic_6_region, vbom);
						Body dynamic4Body = PhysicsFactory.createBoxBody(
								physicsWorld, dynamic4Sprite,
								BodyType.StaticBody, FIXTURE_DEF);
						dynamic4Body.setUserData("dynamic_body_data");
						scene.attachChild(dynamic4Sprite);
						physicsWorld
								.registerPhysicsConnector(new PhysicsConnector(
										dynamic4Sprite, dynamic4Body, true,
										false));
					}
				}
			} else if (mTMXObjectGroup.getTMXObjectGroupProperties()
					.containsTMXProperty("object", "true")) {
				for (TMXObject mTMXObject : mTMXObjectGroup.getTMXObjects()) {
					final float x = mTMXObject.getX();
					final float y = mTMXObject.getY();
					final float width = mTMXObject.getWidth();
					final float height = mTMXObject.getHeight();
					if(mTMXObject.getName().equals("trap_1_5")){
						 
					} else if (mTMXObject.getName().equals("box1")) {
						final Sprite box1Sprite = new Sprite(x, y,
								resourcesManager.unknow_brickover_region, vbom);
						Body box1Body = PhysicsFactory.createBoxBody(
								physicsWorld, box1Sprite, BodyType.StaticBody,
								FIXTURE_DEF);
						box1Body.setUserData("box1_body_data");
						scene.attachChild(box1Sprite);
					} else if (mTMXObject.getName().equals("box1")) {
						box1Sprite = new Sprite(x, y,
								resourcesManager.unknown_region, vbom);
						box1Body = PhysicsFactory.createBoxBody(physicsWorld,
								box1Sprite, BodyType.StaticBody, FIXTURE_DEF);
						box1Body.setUserData("box1_body_data");
						scene.attachChild(box1Sprite);
					} else if (mTMXObject.getName().equals("box2")) {
						box2Sprite = new Sprite(x, y,
								resourcesManager.unknow_brickover_region, vbom);
						box2Body = PhysicsFactory.createBoxBody(physicsWorld,
								box2Sprite, BodyType.StaticBody, FIXTURE_DEF);
						box2Body.setUserData("box2_body_data");
						box2Body.setActive(false);
						box2Sprite.setVisible(false);
						scene.attachChild(box2Sprite);
					} else if (mTMXObject.getName().equals("rec2")) {
						final Rectangle rec2 = new Rectangle(x, y, width,
								height, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);

								if (collidesWith(player)) {
									if (!box2Body.isActive()) {
										box2Body.setActive(true);
									}
								} else {
									if (!box2Sprite.isVisible()) {
										box2Body.setActive(false);
									}
								}
							}
						};
						rec2.setVisible(false);
						scene.attachChild(rec2);
					} else if(mTMXObject.getName().equals("box3")){
						box3Sprite = new Sprite(x, y,
								resourcesManager.unknow_brickover_region, vbom);
						box3Body = PhysicsFactory.createBoxBody(physicsWorld,
								box3Sprite, BodyType.StaticBody, FIXTURE_DEF);
						box3Body.setUserData("box3_body_data");
						box3Body.setActive(false);
						box3Sprite.setVisible(false);
						scene.attachChild(box3Sprite);
					} else if(mTMXObject.getName().equals("rec3")){
						final Rectangle rec3 = new Rectangle(x, y, width,
								height, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);

								if (collidesWith(player)) {
									if (!box3Body.isActive()) {
										box3Body.setActive(true);
									}
								} else {
									if (!box3Sprite.isVisible()) {
										box3Body.setActive(false);
									}
								}
							}
						};
						rec3.setVisible(false);
						scene.attachChild(rec3);
					} else if (mTMXObject.getName().equals("coin")) {
						final Sprite coinSprite = new Sprite(x, y,
								resourcesManager.gold_region, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);

								if (collidesWith(player)) {
									setVisible(false);
									setIgnoreUpdate(true);
								}
							}
						};
						scene.attachChild(coinSprite);
					} else if (mTMXObject.getName().equals("save")) {
						SceneManager.savePositionX = x;
						SceneManager.savePositionY = y;
						final Sprite spriteSave = new Sprite(mTMXObject.getX(),
								mTMXObject.getY(),
								resourcesManager.save_flat_region, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);
								if (collidesWith(player)) {
									SceneManager.saveActivte = true;
									this.setVisible(false);
								}
							}
						};
						scene.attachChild(spriteSave);
					} else if (mTMXObject.getName().equals("rocket")) {
						rocketSprite = new Sprite(x, y,
								resourcesManager.rocket_top_region, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);
								if (collidesWith(player)) {
//									player.setDie(true);
								}
							}
						};
						Path path = new Path(2).to(x, y+64).to(x, -64);
						rocketSprite.registerEntityModifier(new PathModifier(
								0.5f, path, new IPathModifierListener() {

									@Override
									public void onPathWaypointStarted(
											PathModifier pPathModifier,
											IEntity pEntity, int pWaypointIndex) {
										// TODO Auto-generated method stub

									}

									@Override
									public void onPathWaypointFinished(
											PathModifier pPathModifier,
											IEntity pEntity, int pWaypointIndex) {
										// TODO Auto-generated method stub

									}

									@Override
									public void onPathStarted(
											PathModifier pPathModifier,
											IEntity pEntity) {
										// TODO Auto-generated method stub

									}

									@Override
									public void onPathFinished(
											PathModifier pPathModifier,
											IEntity pEntity) {
										if (rocketSprite.isVisible()) {
											rocketSprite.setVisible(false);
										}
										rocketSprite.setIgnoreUpdate(true);
									}
								}, EaseSineInOut.getInstance()));
					} else if(mTMXObject.getName().equals("recrocket")){
						final Rectangle recRocket = new Rectangle(x, y, width, height, vbom){
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);
								if(collidesWith(player)){
									if(!doRocket){
										doRocket = true;
										scene.attachChild(rocketSprite);
										setIgnoreUpdate(true);
									}
								}
							}
						};
						recRocket.setVisible(false);
						scene.attachChild(recRocket);
					} else if (mTMXObject.getName().equals("lady")) {
						final Sprite spriteLady = new Sprite(x, y,
								resourcesManager.lady_region, vbom) {
							@Override
							protected void onManagedUpdate(float pSecondsElapsed) {
								// TODO Auto-generated method stub
								super.onManagedUpdate(pSecondsElapsed);
								if (collidesWith(player)) {
									if (!levelCompleteDisplayed) {
										levelCompleteDisplayed = true;
										scene.displayLevelComplete(SceneManager.currentLevel);
										// levelCompleteWindow.display(0, scene,
										// camera);
									}
								}
							}
						};
						scene.attachChild(spriteLady);
					} else if (mTMXObject.getName().equals("player")) {
						if (!SceneManager.saveActivte) {
							SceneManager.savePositionX = x;
							SceneManager.savePositionY = y;
						}
						player = new Player(SceneManager.savePositionX,
								SceneManager.savePositionY, vbom, camera,
								physicsWorld) {

							@Override
							public void onDie() {
								if (!gameOverDisplayed) {
									gameOverDisplayed = true;
									if (!ResourcesManager.getInstance().die_sound
											.isPlaying()) {
										ResourcesManager.getInstance().die_sound
												.play();
									}
									scene.displayGamOver();
								}

							}
						};

						scene.attachChild(player);
					}
				}
			}
		}

		return player;
	}

	@Override
	protected ContactListener contactListener() {
		ContactListener contactListener = new ContactListener() {

			@Override
			public void preSolve(Contact contact, Manifold oldManifold) {
				// TODO Auto-generated method stub

			}

			@Override
			public void postSolve(Contact contact, ContactImpulse impulse) {
				// TODO Auto-generated method stub

			}

			@Override
			public void endContact(Contact contact) {
				final Fixture x1 = contact.getFixtureA();
				final Fixture x2 = contact.getFixtureB();
				if (x1.getBody().getUserData() != null
						&& x2.getBody().getUserData() != null) {
					if (x1.getBody().getUserData().equals("player")
							|| x2.getBody().getUserData().equals("player")) {
						player.decreaseFootContacts();
					}
				}

			}

			@Override
			public void beginContact(Contact contact) {
				final Fixture x1 = contact.getFixtureA();
				final Fixture x2 = contact.getFixtureB();
				if (x1.getBody().getUserData() != null
						&& x2.getBody().getUserData() != null) {
					final Object x1_body_data = x1.getBody().getUserData();
					final Object x2_body_data = x2.getBody().getUserData();
					if (x1_body_data.equals("player")
							|| x2_body_data.equals("player")) {
						player.increaseFootContacts();

						if (x1_body_data.equals("dynamic_body_data")
								|| x2_body_data.equals("dynamic_body_data")) {
							// engine.registerUpdateHandler(new
							// TimerHandler(0.05f, new ITimerCallback() {
							//
							// @Override
							// public void onTimePassed(TimerHandler
							// pTimerHandler) {
							// engine.unregisterUpdateHandler(pTimerHandler);
							// if(x1_body_data.equals("dynamic_body_data")){
							// x1.getBody().setType(BodyType.DynamicBody);
							// } else{
							// x2.getBody().setType(BodyType.DynamicBody);
							// }
							// }
							// }));
						} else if(x1_body_data.equals("box2_body_data") || x2_body_data.equals("box2_body_data")){
							if(box2Body.isActive()){
								box2Sprite.setVisible(true);
							}
						} else if(x1_body_data.equals("box3_body_data") || x2_body_data.equals("box3_body_data")){
							if(box3Body.isActive()){
								box3Sprite.setVisible(true);
							}
						}
					}
				}

			}
		};
		return contactListener;
	}

}
